package com.hotel.BL;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.Counter;
import data.POS;
import data.POSTax;

public class POSLogic extends AbstractBL {
	public POSLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}

	public List<POS> GeneratePOS(long hotelId)
	{
		List<Counter> counter = new CounterLogic().GetAllCounter(1);
		List<POSTax> tl = new POSTaxLogic(req,resp).GetAllPOSTax(hotelId);
		String defaultCounterString = String.valueOf(counter.get(0).getId());
		String counterString = "";
		for(int i=0;i<counter.size();i++){
			counterString += counter.get(i).getId() + ",";
		}
		counterString = counterString.substring(0, counterString.length()-1);
		List<POS> list = new ArrayList<POS>();
		POS c;
		if(GetPOS(hotelId,"iChic") == null){
			c = new POS();
			c.setHotelId(hotelId);
			c.setTitle("iChic");
			c.setDescription("iChic");
			c.setPospointId(null);
			c.setProduct(true);
			c.setTable(false);
			c.setListPOSTax(tl);
			c.setDefaultCounterString(defaultCounterString);
			c.setCounterString(defaultCounterString);
			list.add(c);
		}
		if(GetPOS(hotelId,"iCoffee") == null){
			c = new POS();
			c.setHotelId(hotelId);
			c.setTitle("iCoffee");
			c.setDescription("iCoffee");
			c.setPospointId(null);
			c.setProduct(true);
			c.setTable(false);
			c.setDefaultCounterString(defaultCounterString);
			c.setCounterString(counterString);
			list.add(c);
		}
		
		if(GetPOS(hotelId,"iFront") == null){
			c = new POS();
			c.setHotelId(hotelId);
			c.setTitle("iFront");
			c.setDescription("iFront");
			c.setPospointId(null);
			c.setProduct(true);
			c.setTable(false);
			c.setDefaultCounterString(defaultCounterString);
			c.setCounterString(counterString);
			list.add(c);
		}
		return list;
	}
	
	public POS GetPOS(long id)
	{
		Key key = KeyFactory.createKey(EntityName.POS, id);
		try {
			Entity en = datastore.get(key);
			POS c = new POS();
			c.setEntity(en);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}
	
	public POS GetPOS(Entity entity)
	{
		if(entity == null) return null;
		POS item = new POS();
		item.setEntity(entity);
		return item;
	}
	
	public POS GetPOS(long hotelId,String title)
	{
		Query q = new Query(EntityName.POS);
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterStatus = new FilterPredicate("status",FilterOperator.EQUAL,true);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filterTitle = new FilterPredicate("Title",FilterOperator.EQUAL,title);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterStatus, filterAvaliable,filterTitle);
		
		q.setFilter(filter);
		
		return GetPOS(datastore.prepare(q).asSingleEntity());
	}
	
	public List<POS> GetAllPOSLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.POS);
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		q.setFilter(filter);
		return GetPOSList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset)));
	}
	public List<POS> GetAllPOS(long hotelId) {
		Query q = new Query(EntityName.POS);
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterStatus = new FilterPredicate("status",FilterOperator.EQUAL,true);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);
		Filter filter = CompositeFilterOperator.and(filterHotel, filterStatus,filterAvaliable);
		q.setFilter(filter);
		return GetPOSList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
	}

	public List<POS> GetPOSList(List<Entity> entities)
	{
		List<POS> list = new ArrayList<POS>();
		if(entities!=null)
			for(Entity e : entities)
			{
				POS a = new POS();
				a.setEntity(e);
				list.add(a);
			}
		return list;
	}
	
	public POS AddPOSPoint(long id,String title,String description,String pospointId,boolean table,boolean product,String listcounter,String defaultcounter,String taxuse) throws EntityNotFoundException{
		POS a = new POS();
		a.setHotelId(id);
		a.setTitle(title);
		a.setDescription(description);
		a.setPospointId(pospointId);
		a.setTable(table);
		a.setProduct(product);
		a.setListPOSTaxString(taxuse);
		a.setCounterString(listcounter);
		a.setDefaultCounterString(defaultcounter);
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public POS EditPOSPoint(long id,String title,String description,String pospointId,boolean table,boolean product,String listcounter,String defaultcounter,String taxuse) throws EntityNotFoundException{
		POS a = GetPOS(id);
		a.setTitle(title);
		a.setDescription(description);
		a.setPospointId(pospointId);
		a.setTable(table);
		a.setProduct(product);
		a.setListPOSTaxString(taxuse);
		a.setCounterString(listcounter);
		a.setDefaultCounterString(defaultcounter);
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public POS EditPOSCounter(long posId,long counterId) throws EntityNotFoundException{
		POS a = GetPOS(posId);
		String counterString = String.valueOf(counterId);
		if(a.getCounterString()!=null&&!a.getCounterString().equals("")){
			String oldCounter = a.getCounterString();
			oldCounter = oldCounter+","+counterString;
			a.setCounterString(oldCounter);
		}else{
			a.setCounterString(counterString);
		}
		
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public POS DeletePOSCounter(long posId,long counterId) throws EntityNotFoundException{
		POS a = GetPOS(posId);
		String counterString = String.valueOf(counterId);
		if(a.getCounterString()!=null){
			String[] arrayCounter = a.getCounterString().split(",");
			String newCounter = "";
			for(int i=0;i<arrayCounter.length;i++){
				if(!arrayCounter[i].equals(counterString)){
					newCounter += arrayCounter[i]+",";
				}
			}
			//String newCounterArray[] = newCounter.split(",");
			if(newCounter.length()!=0)
				newCounter = newCounter.substring(0,newCounter.length() - 1);
			else
				newCounter = "";
			a.setCounterString(newCounter);
		}
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public POS ChangeStatusPosPoint(long posId) throws EntityNotFoundException{
		POS a = GetPOS(posId);
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);
		return a;
	}
	
	public POS DeletePOSPoint(long pospointId) throws EntityNotFoundException{
		POS a = GetPOS(pospointId);
		a.setAvaliable(false);
		a.setStatus(false);
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return a;
	}
	
	public List<HashMap<String,Object>> OnlyIdAndTitle(List<POS> list){
		List<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>();
		for(int i=0;i<list.size();i++){
			HashMap<String,Object> map = new HashMap<String, Object>();
			map.put("id", list.get(i).getId());
			map.put("title", list.get(i).getTitle());
			data.add(map);
		}
		return data;
	}
	
	public POS UpdatePOS(POS pos) throws EntityNotFoundException
	{
		Key key = datastore.put(pos.getEntity());
		pos.setId(key.getId());
		pos.setKey(key);
		return pos;
	}
}
